package licode.unisop.client.service.filter;

import licode.unisop.client.api.SopPlatform;
import licode.unisop.client.api.SopPlatformMng;
import licode.unisop.client.info.SiRoleAction;
import licode.unisop.client.inter.HasRoles;
import licode.unisop.client.utils.SopErrorCode;
import licode.unisop.client.utils.SopException;
import licode.unisop.client.vo.SopVerifyCode;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author licode
 */
@Aspect
@Configuration
public class SopRoleAspect {
    @Resource
    private SopPlatformMng platformMng;

    @Pointcut("@annotation(licode.unisop.client.inter.HasRoles)")
    public void hasRoleVerify() {
    }

    /**
     * 登录验证
     *
     * @param joinPoint 连接点
     */
    @Before("hasRoleVerify()")
    public void doAdminAuthVerify(JoinPoint joinPoint) {
        SopVerifyCode checkCode;
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 判断是否进行权限验证
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        // 从切面中获取当前方法
        Method method = signature.getMethod();

        // 从方法处获取其注解注解
        HasRoles action = method.getAnnotation(HasRoles.class);
        String pfType = action.platform();
        SopPlatform platform = platformMng.getPlatform(pfType);

        if (null == platform) {
            throw new SopException(SopErrorCode.PLATFORM_NOT_REGISTER,
                    SopErrorCode.PLATFORM_NOT_REGISTER_MSG);
        }

        checkCode = platform.hasRole(SiRoleAction.builder()
                .role(action.role())
                .all(action.all())
                .build());
        if (checkCode.isNoLogin()) {
            throw new SopException(SopErrorCode.USER_NOT_LOGIN,
                    SopErrorCode.USER_NOT_LOGIN_MSG);
        } else if (!checkCode.isOk()) {
            throw new SopException(SopErrorCode.FORBIDDEN_ROLE_GRAND,
                    SopErrorCode.FORBIDDEN_ROLE_GRAND_MSG);
        }
    }
}
